package cn.com.nes.site.service.system.callCenter.impl;

import cn.com.nes.common.em.platform.CallMethodEnum;
import cn.com.nes.common.exception.ApiCallFailedException;
import cn.com.nes.common.exception.IllegalBusinessException;
import cn.com.nes.common.util.HttpUtils;
import cn.com.nes.mybatis.callcenter.entity.CcUser;
import cn.com.nes.mybatis.callcenter.mapper.CallCenterCompanyMapper;
import cn.com.nes.mybatis.callcenter.mapper.CcUserMapper;
import cn.com.nes.mybatis.callcenter.mapper.CompanyAttachMapper;
import cn.com.nes.site.entity.bo.user.GetInstallPersonListBO;
import cn.com.nes.site.entity.bo.user.PushCallCenterUserInfoBO;
import cn.com.nes.site.entity.bo.workorder.GetWorkOrderInstallDetailBO;
import cn.com.nes.site.entity.bo.workorder.GetWorkOrderInstallPageBO;
import cn.com.nes.site.entity.bo.workorder.SaveWorkOrderBO;
import cn.com.nes.site.entity.vo.comecall.ComecallVo;
import cn.com.nes.site.service.comecall.entity.CompanyAttach;
import cn.com.nes.site.service.system.callCenter.CallCenterService;
import cn.com.nes.site.service.system.callCenter.bo.CallCenterApplyBO;
import cn.com.nes.site.service.system.callCenter.bo.CallCenterApplyCheckBO;
import cn.com.nes.site.service.system.callCenter.dto.CompanyApplyPageDto;
import cn.com.nes.site.service.system.company.BusinessCompanyService;
import cn.com.nes.site.service.workOrder.dto.WorkOrderInstallDetailDTO;
import cn.com.nes.site.service.workOrder.dto.callCenter.WorkOrderInstallPageDTO;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 长效管护 - 客服中心 服务实现
 */
@Slf4j
@Service
public class CallCenterServiceImpl implements CallCenterService {

    @Resource
    CallCenterCompanyMapper callCenterCompanyMapper;
    @Resource
    private BusinessCompanyService businessCompanyService;
    @Resource
    CcUserMapper ccUserMapper;
    @Resource
    CompanyAttachMapper companyAttachMapper;

    /**
     * 获取长效管护token
     * 根据入参的公司id,获取这个公司的管理员账号的token
     * 那为什么需要获取这个公司的管理员账号token呢？
     *  -- 1、是因为从热链云提交一个客服中心申请，长效管护审通过后，要把这个公司在热链云维护的全部人员账号同步到长效管护；
     *  -- 2、如果热链云里面的公司在长效管护已经有一个客服中心了，那么之后热链云创建的该公司用户也要同步到长效管护；
     *  -- 3、以上两个情况都需要调用长效管护的接口【/user/saveUserServiceStaff】，这个接口是长效管护创建坐席人员的接口，创建的账号的公司id写死为当前登录人的公司id。
     *      -- 长效管护示例代码：【user.setCompanyId(saveUserVo.getCompanyId());】
     *  -- 4、所以想要在长效管护创建当前公司下的人员账号，只能先获取当前公司的管理员账号token，再调用创建用户账号接口；
     * 备注：这个获取token的接口只适用于创建长效管护用户账号，或者需要某公司的管理员账号权限，其他情况严禁使用！！！
     * 为了提高代码可读性，单独调长效管护获取token接口，但是这样不好，有需求是在for循环里面调长效管护接口，这样需要重复多次地调用获取token接口；
     */
    private Map<String, String> getCcHeader(Long companyId) throws Exception {
        if (Objects.isNull(companyId)) {
            throw new Exception("companyId 为空!");
        }
        JSONObject paramJson = new JSONObject();
        paramJson.put("account","nmxl123");
        paramJson.put("companyId", companyId);
        log.debug("paramJson:{}", paramJson);
        String apiUrl = CallMethodEnum.callCenterToken.url();
        String apiResponse = HttpUtils.sendJSONPost(apiUrl, paramJson.toJSONString());
        // log.debug("Api回复 - {} : {}", apiUrl, apiResponse);
        JSONObject apiResponseJson = analysisResult(apiResponse, apiUrl);

        Map<String, String> header = new HashMap<>();
        header.put("token", apiResponseJson.getJSONObject("data").getOrDefault("token", "").toString());
        return header;
    }

    /**
     * 获取权限Token
     * @param agentUserUuid       热链云用户UUID
     * @param callCenterCompanyId 长效管护公司ID
     * @return
     */
    private String getAuthToken(String agentUserUuid, String callCenterCompanyId) throws Exception {
        JSONObject paramJson = new JSONObject();
        paramJson.put("account", getUser(agentUserUuid).getAccount());
        paramJson.put("companyId", callCenterCompanyId);
        log.info("paramJson:{}", paramJson);
        String apiUrl = CallMethodEnum.callCenterToken.url();
        String apiResponse = HttpUtils.sendJSONPost(apiUrl, paramJson.toJSONString());
        log.info("Api回复 - {} : {}", apiUrl, apiResponse);
        JSONObject apiResponseJson = JSON.parseObject(apiResponse);
        if (!apiSuccessed(apiResponseJson)) {
            log.error("ApiResponse - [{}] -> {}", apiUrl, ObjectUtil.isNull(apiResponseJson) ? "接口无返回" : "系统异 - 工单服务调用失败：" + apiResponseJson.getString("retMessage"));
            throw new ApiCallFailedException("工单服务调用失败！");
        }
        return apiResponseJson.getJSONObject("data").getOrDefault("token", "").toString();
    }

    private boolean apiSuccessed(JSONObject apiResponseJson) {
        if (ObjectUtil.isNotNull(apiResponseJson) && 0 == apiResponseJson.getInteger("code")) {
            return true;
        }
        return false;
    }

    private CcUser getUser(String agentUserUuid) throws Exception {
        CcUser ccUser = ccUserMapper.getUserByAgentId(agentUserUuid);
        if (Objects.isNull(ccUser)) {
            throw new IllegalBusinessException("长效管护用户不存在");
        }
        return ccUser;
    }

    private CcUser getUserByAccount(String callcenterUserAccount) throws Exception {
        CcUser ccUser = ccUserMapper.selectByAccout(callcenterUserAccount);
        if (Objects.isNull(ccUser)) {
            throw new IllegalBusinessException("长效管护用户不存在");
        }
        return ccUser;
    }

    // 解析返回值
    private JSONObject analysisResult(String result, String apiUrl) throws Exception {
        JSONObject apiResponseJson = JSON.parseObject(result);
        if (ObjectUtil.isNotNull(apiResponseJson) && 0 == apiResponseJson.getInteger("code")) {
            return apiResponseJson;
        } else if (ObjectUtil.isNotNull(apiResponseJson) && 0 != apiResponseJson.getInteger("code")) {
            throw new ApiCallFailedException(apiResponseJson.getString("msg"));
        } else {
            log.error("ApiResponse - [{}] -> {}", apiUrl, ObjectUtil.isNull(apiResponseJson) ? "接口无返回" : "系统异 - 工单服务调用失败：" + apiResponseJson.getString("retMessage"));
            throw new ApiCallFailedException("系统异常，工单服务调用失败！");
        }
    }

    @Override
    public String pushCallCenterUser(PushCallCenterUserInfoBO callCenterUserInfoBo) throws Exception {
        Map<String, String> header = getCcHeader(callCenterUserInfoBo.getCompanyId());
        // 参数
        JSONObject paramJson = JSON.parseObject(JSON.toJSONString(callCenterUserInfoBo));
        log.info("paramJson: {}", paramJson);
        // 获取接口url
        String apiUrl = CallMethodEnum.SAVE_USER_SERVICE_STAFF.url();
        log.info("pushCallCenterUserUrl: {}", apiUrl);
        // 调接口
        String result = HttpUtils.sendPost(apiUrl, paramJson.toJSONString(), header);
        log.info("pushCallCenterUserResult:{}", result);
        // 解析返回值
        JSONObject apiResponseJson = analysisResult(result, apiUrl);
        log.info("创建客服中心账号成功,userId:{}", apiResponseJson.get("data"));
        return String.valueOf(apiResponseJson.get("data"));
    }

    @Override
    public void updateCallCenterUser(PushCallCenterUserInfoBO callCenterUserInfoBo) throws Exception {
        Map<String, String> header = getCcHeader(callCenterUserInfoBo.getCompanyId());
        // 参数
        JSONObject paramJson = JSON.parseObject(JSON.toJSONString(callCenterUserInfoBo));
        log.info("paramJson: {}", paramJson);
        // 获取接口url
        String apiUrl = CallMethodEnum.UPDATE_USER_SERVICE_STAFF.url();
        log.info("updateCallCenterUserUrl: {}", apiUrl);
        // 调接口
        String result = HttpUtils.sendPost(apiUrl, paramJson.toJSONString(), header);
        log.info("updateCallCenterUserResult:{}", result);
        // 解析返回值
        analysisResult(result, apiUrl);
        log.info("修改客服中心账号成功,userId:{}", callCenterUserInfoBo.getUserId());
    }

    @Override
    public void deleteCallCenterUser(Long oldCallCenterUserId, Long callCenterCompanyId) throws Exception {
        Map<String, String> header = getCcHeader(callCenterCompanyId);
        // 参数
        JSONObject paramJson = new JSONObject();
        paramJson.put("id", oldCallCenterUserId);
        paramJson.put("dataSource", "agent");
        log.info("paramJson: {}", paramJson);
        // 获取接口url
        String apiUrl = CallMethodEnum.DELETE_USER_SERVICE_STAFF.url();
        log.info("deleteCallCenterUserUrl: {}", apiUrl);
        // 调接口
        String result = HttpUtils.sendPost(apiUrl, paramJson.toJSONString(), header);
        log.info("deleteCallCenterUserResult:{}", result);
        // 解析返回值
        analysisResult(result, apiUrl);
        log.info("删除客服中心账号成功！");
    }

    @Override
    public Object getInstallPersonList(GetInstallPersonListBO getInstallPersonListBo) throws Exception {
        // 组装token
        String token = getAuthToken(getInstallPersonListBo.getUserInfo().getUuid(), getInstallPersonListBo.getUserInfo().getCallCenterCompanyId());
        Map<String, String> header = new HashMap<>();
        header.put("token", token);
        log.info("getInstallPersonListHeader:{}", header);

        // url
        String apiUrl = CallMethodEnum.INSTALL_PERSON_LIST.url();
        log.info("getInstallPersonListUrl:{}", apiUrl);

        // 调接口
        String result = HttpUtils.sendGet(apiUrl, "", header);
        log.info("getInstallPersonListResult:{}", result);

        // 解析返回值
        JSONObject apiResponseJson = analysisResult(result, apiUrl);
        log.info("安装人员列表:{}", apiResponseJson.get("data"));

        return apiResponseJson.get("data");
    }

    /**
     * 创建工单
     * @param saveWorkOrderBo
     */
    @Override
    public Long createWorkOrder(SaveWorkOrderBO saveWorkOrderBo,String url) throws Exception {
        // 组装token
        String token = getAuthToken(saveWorkOrderBo.getUserInfo().getUuid(), saveWorkOrderBo.getUserInfo().getCallCenterCompanyId());
        Map<String, String> header = new HashMap<>();
        header.put("token", token);

        JSONObject paramJson = JSON.parseObject(JSON.toJSONString(saveWorkOrderBo));

        String result = HttpUtils.sendPost(url, paramJson.toJSONString(), header);
        log.info("Api回复 - {} : {}", url, result);

        JSONObject apiResponseJson = analysisResult(result, url);
        Map<String, Object> map = JSON.parseObject(JSON.toJSONString(apiResponseJson.get("data")), Map.class);
        return Long.valueOf(String.valueOf(map.get("id")));
    }

    @Override
    public WorkOrderInstallPageDTO getWorkOrderInstallPage(GetWorkOrderInstallPageBO getWorkOrderInstallPageBo) throws Exception {
        // 组装token
        String token = getAuthToken(getWorkOrderInstallPageBo.getUserInfo().getUuid(), getWorkOrderInstallPageBo.getUserInfo().getCallCenterCompanyId());
        Map<String, String> header = new HashMap<>();
        header.put("token", token);
        header.put("traceId", getWorkOrderInstallPageBo.getTraceId());
        log.info("getWorkOrderInstallPageHeader:{}", header);

        // url
        String apiUrl = CallMethodEnum.GET_WORK_ORDER_INSTALL_PAGE.url();
        log.info("getWorkOrderInstallPageUrl:{}", apiUrl);

        // 参数
        JSONObject paramJson = new JSONObject();
        paramJson.put("workOrderState", getWorkOrderInstallPageBo.getWorkOrderState());
        paramJson.put("orderType", getWorkOrderInstallPageBo.getOrderType());
        paramJson.put("type", getWorkOrderInstallPageBo.getType());
        paramJson.put("page", getWorkOrderInstallPageBo.getPage());
        paramJson.put("size", getWorkOrderInstallPageBo.getSize());
        log.info("getWorkOrderInstallPageParamJson: {}", paramJson);

        // 调接口
        String result = HttpUtils.sendPost(apiUrl, paramJson.toJSONString(), header);
        log.info("getWorkOrderInstallPageResult:{}", result);

        // 解析返回值
        JSONObject apiResponseJson = analysisResult(result, apiUrl);
        log.info("安装工单分页:{}", apiResponseJson.get("data"));

        return JSON.parseObject(JSON.toJSONString(apiResponseJson.get("data")), WorkOrderInstallPageDTO.class);
    }

    @Override
    public WorkOrderInstallDetailDTO getWorkOrderInstallDetail(GetWorkOrderInstallDetailBO getWorkOrderInstallDetailBo) throws Exception {
        // 组装token
        String token = getAuthToken(getWorkOrderInstallDetailBo.getOrderCreateUserId(), getWorkOrderInstallDetailBo.getOrderBelongCompanyId());
        Map<String, String> header = new HashMap<>();
        header.put("token", token);
        header.put("traceId", getWorkOrderInstallDetailBo.getTraceId());
        log.info("getWorkOrderInstallDetailHeader:{}", header);

        // url
        String apiUrl = CallMethodEnum.GET_WORK_ORDER_INSTALL_DETAIL.url();
        log.info("getWorkOrderInstallDetailUrl:{}", apiUrl);

        // 参数
        StringBuilder paramJson = new StringBuilder();
        paramJson.append("id=").append(getWorkOrderInstallDetailBo.getWorkOrderId());
        if (ObjectUtil.isNotNull(getWorkOrderInstallDetailBo.getQueryPriceMasterInfo())) {
            paramJson.append("&queryPriceMasterInfo=").append(getWorkOrderInstallDetailBo.getQueryPriceMasterInfo());
        }
        log.info("getWorkOrderInstallDetailParamJson: {}", paramJson);

        // 调接口
        String result = HttpUtils.sendGet(apiUrl, paramJson.toString(), header);
        log.info("getWorkOrderInstallDetailResult:{}", result);

        // 解析返回值
        JSONObject apiResponseJson = analysisResult(result, apiUrl);
        log.info("安装工单详情:{}",apiResponseJson.get("data"));

        return JSON.parseObject(JSON.toJSONString(apiResponseJson.get("data")), WorkOrderInstallDetailDTO.class);
    }

    @Override
    public Page<CompanyApplyPageDto> getCallCenterApplyPage(CallCenterApplyBO bo) throws Exception {
        Page<CompanyApplyPageDto> page = new Page<>(bo.getPageid(),bo.getPagesize());
        String apiUrl = CallMethodEnum.COMPANY_APPLY_PAGE.url();
        Map<String, String> header = getCcHeader(Long.valueOf(bo.getUserInfo().getCallCenterCompanyId()));
        JSONObject paramJson = JSON.parseObject(JSON.toJSONString(bo));
        paramJson.put("page", bo.getPageid());
        paramJson.put("size", bo.getPagesize());
        JSONObject apiResponseJson = HttpUtils.post(apiUrl, header, paramJson);
        if (!apiSuccessed(apiResponseJson)) {
            log.error("ApiResponse - [{}] -> {}", apiUrl, ObjectUtil.isNull(apiResponseJson) ? "接口无返回" : "系统异常 - 客服中心申请分页API调用失败：" + apiResponseJson.getString("msg"));
            throw new ApiCallFailedException(apiResponseJson.getString("msg"));
        }
        page.setTotal(apiResponseJson.getJSONObject("data").getInteger("total"));
        page.setRecords(apiResponseJson.getJSONObject("data").getList("list", CompanyApplyPageDto.class));
        return page;
    }

    @Override
    public void callCenterApplyCheck(CallCenterApplyCheckBO bo) throws Exception {
        String apiUrl = CallMethodEnum.COMPANY_APPLY_CHECK.url();
        System.out.println(apiUrl);
        JSONObject apiResponseJson = HttpUtils.post(apiUrl, getCcHeader(Long.valueOf(bo.getUserInfo().getCallCenterCompanyId())), JSON.parseObject(JSON.toJSONString(bo)));
        if (!apiSuccessed(apiResponseJson)) {
            log.error("ApiResponse - [{}] -> {}", apiUrl, ObjectUtil.isNull(apiResponseJson) ? "接口无返回" : "系统异常 - 客服中心申请审核API调用失败：" + apiResponseJson.getString("msg"));
            throw new ApiCallFailedException(apiResponseJson.getString("msg"));
        }else{
          JSONObject jsonObject=JSONObject.parseObject(apiResponseJson.get("data").toString());
          if(!businessCompanyService.updateCompany(jsonObject.getString("agentCompanyId"),jsonObject.getString("callCenterCompanyId"))){
              throw new ApiCallFailedException("更新客服中心id失败");
          }
        }
    }


    @Override
    public Object forward(String str,ComecallVo vo) throws Exception {
        CompanyAttach companyAttach = companyAttachMapper.queryCompanyAttach(vo.getOperateUserCallCenterCompanyId());
        str+="&companyAttachId="+companyAttach.getId();
        String apiUrl = CallMethodEnum.FORWARD.url();
        System.out.println(apiUrl);
        JSONObject apiResponseJson = HttpUtils.get(apiUrl, getCcHeader(Long.valueOf(vo.getUserInfo().getCallCenterCompanyId())),str);
        if (!apiSuccessed(apiResponseJson)) {
            log.error("ApiResponse - [{}] -> {}", apiUrl, ObjectUtil.isNull(apiResponseJson) ? "接口无返回" : "系统异常 - 客服中心申请审核API调用失败：" + apiResponseJson.getString("msg"));
            throw new ApiCallFailedException(apiResponseJson.getString("msg"));
        }else{
            return JSONObject.parseObject(apiResponseJson.get("data").toString());
        }
    }
}
